// #include <iostream>
// #include <memory>

// // 水果类 -- 抽象类
// class Fruit
// {
// public:
// 	virtual void name() = 0;
// };

// class Apple : public Fruit
// {
// public:
// 	void name() override
// 	{
// 		std::cout << "我是一个苹果" << std::endl;
// 	}
// };

// // 水果产品 -- 苹果 香蕉
// class Banana : public Fruit
// {
// public:
// 	void name() override
// 	{
// 		std::cout << "我是一个香蕉" << std::endl;
// 	}
// };

// // 水果工厂
// // class FruitFactory
// // {
// // public:
// // 	static std::shared_ptr<Fruit> create(const std::string &name)
// // 	{
// // 		if (name == "苹果")
// // 			return std::make_shared<Apple>();
// // 		else
// // 			return std::make_shared<Banana>();
// // 	}
// // };

// // 水果工厂 -- 抽象类
// class FruitFactory
// {
// public:
// 	virtual std::shared_ptr<Fruit> create() = 0;
// };

// // 苹果工厂
// class AppleFactory : public FruitFactory
// {
// public:
//     virtual std::shared_ptr<Fruit> create() override // 用来重写基类的同名虚函数
//     {
//         return std::make_shared<Apple>();
//     }
// };
// // 香蕉工厂
// class BananFactory : public FruitFactory
// {
// public:
//     virtual std::shared_ptr<Fruit> create() override // 用来重写基类的同名虚函数
//     {
//         return std::make_shared<Banana>();
//     }
// };


// int main()
// {
// 	// std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
// 	// fruit->name();
// 	// fruit = FruitFactory::create("香蕉");
// 	// fruit->name();

// 	std::shared_ptr<FruitFactory> ff(new AppleFactory()); // 创建一个苹果工厂
//     std::shared_ptr<Fruit> fruit = ff->create();          // 生产苹果
//     fruit->name();
//     ff.reset(new BananFactory()); // 重新设置工厂为香蕉工厂
//     fruit = ff->create();         // 生产香蕉
//     fruit->name();                
//     return 0;


// 	return 0;
// }

#include<iostream>
#include<memory>

class Fruit
{
public:
    Fruit() {}
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    Apple() {}
    virtual void name()
    {
        std::cout << "我是一个苹果" << std::endl;
    }
};

class Banana : public Fruit
{
public:
    Banana() {}
    virtual void name()
    {
        std::cout << "我是一个香蕉" << std::endl;
    }
};

class Animal
{
public:
    virtual void name() = 0;
};

class Lamp : public Animal
{
public:
    virtual void name()
    {
        std::cout << "我是山羊" << std::endl;
    }
};

class Dog : public Animal
{
public:
    virtual void name()
    {
        std::cout << "我是小狗" << std::endl;
    }
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string &name) = 0;
    virtual std::shared_ptr<Animal> GetAnimal(const std::string &name) = 0;
};

class FruitFactory : public Factory
{
public:
	// 纯虚函数必须重写
    virtual std::shared_ptr<Animal> GetAnimal(const std::string &name)
    {
        return std::shared_ptr<Animal>(); // 返回一个空对象
    }
    virtual std::shared_ptr<Fruit> GetFruit(const std::string &name)
    {
        if(name ==  "苹果")
        {
            return std::make_shared<Apple>();
        }
        else if(name == "香蕉")
        {
            return std::make_shared<Banana>();
        }
    }
};

class AnimalFactory : public Factory
{
public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string &name)
    {
        return std::shared_ptr<Fruit>();
    }
    virtual std::shared_ptr<Animal> GetAnimal(const std::string &name)
    {
        if(name ==  "山羊")
        {
            return std::make_shared<Lamp>();
        }
        else if(name == "小狗")
        {
            return std::make_shared<Dog>();
        }
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factory> getFactory(const std::string &name)
    {
        if(name == "动物")
        {
            return std::make_shared<AnimalFactory>();
        }
        else 
        {
            return std::make_shared<FruitFactory>();
        }
    }
};


int main()
{
    std::shared_ptr<Factory> ff = FactoryProducer::getFactory("水果");
    std::shared_ptr<Fruit> f = ff->GetFruit("香蕉");
    f->name();
    f = ff->GetFruit("苹果");
    f->name();

    std::shared_ptr<Factory> af = FactoryProducer::getFactory("动物");
    std::shared_ptr<Animal> a = af->GetAnimal("山羊");
    a->name();
    a = af->GetAnimal("小狗");
    a->name();

    return 0;
}